<template>
  <div class="rich-text-editor-container" :style="{ width: width, height: height }">
    <!-- 只在非只读模式下显示工具栏 -->
    <div class="editor-toolbar-container">
      <Toolbar
        :editor="editorRef"
        :defaultConfig="toolbarConfig"
        :mode="mode"
      />
    </div>
    <div class="editor-content-container">
      <Editor
        v-model="valueHtml"
        :defaultConfig="editorConfig"
        :mode="mode"
        @onCreated="handleCreated"
        @onChange="handleChange"
      />
    </div>
    
    <!-- 上传进度提示 -->
    <el-dialog
      v-model="uploadDialogVisible"
      title="文件上传"
      width="30%"
      :close-on-click-modal="false"
      :show-close="false"
    >
      <el-progress :percentage="uploadProgress" :status="uploadStatus" />
      <div class="upload-filename">{{ uploadFilename }}</div>
      <template #footer>
        <el-button v-if="uploadStatus === 'exception'" type="primary" @click="uploadDialogVisible = false">关闭</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import '@wangeditor-next/editor/dist/css/style.css'
import { Editor, Toolbar } from '@wangeditor-next/editor-for-vue'
import { ElMessage } from 'element-plus'
import FileAPI from '@/api/file.api'
import { ref, reactive, watch, onBeforeUnmount, shallowRef } from 'vue'

// Props
const props = defineProps({
  modelValue: {
    type: String,
    default: ''
  },
  width: {
    type: String,
    default: '100%'
  },
  height: {
    type: String,
    default: '500px'
  },
  mode: {
    type: String,
    default: 'default', // 'default' 或 'simple'
    validator: (value) => ['default', 'simple'].includes(value)
  },
  uploadConfig: {
    type: Object,
    default: () => ({
      imageServer: '/api/v1/files',
      videoServer: '/api/v1/files',
      maxImageSize: 10 * 1024 * 1024, // 10MB
      maxVideoSize: 100 * 1024 * 1024, // 100MB
      allowedImageTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/bmp', 'image/webp'],
      allowedVideoTypes: ['video/mp4', 'video/avi', 'video/mov', 'video/wmv', 'video/flv', 'video/webm']
    })
  }
})

// Emits
const emit = defineEmits(['update:modelValue', 'change', 'created'])

// 响应式数据
const editorRef = shallowRef()
const valueHtml = ref(props.modelValue)
const uploadDialogVisible = ref(false)
const uploadProgress = ref(0)
const uploadStatus = ref('')
const uploadFilename = ref('')

// 监听 modelValue 变化
watch(() => props.modelValue, (newVal) => {
  if (newVal !== valueHtml.value && editorRef.value) {
    editorRef.value.setHtml(newVal)
  }
})

// 显示上传对话框
function showUploadDialog(message, filename) {
  uploadDialogVisible.value = true
  uploadProgress.value = 0
  uploadStatus.value = ''
  uploadFilename.value = `${message}: ${filename}`
}

// 更新上传进度
function updateUploadProgress(progress) {
  uploadProgress.value = progress
}

// 更新上传状态
function updateUploadStatus(status) {
  uploadStatus.value = status
}

// 隐藏上传对话框
function hideUploadDialog() {
  setTimeout(() => {
    uploadDialogVisible.value = false
  }, 500)
}

// 自定义图片上传
function customImageUpload(file, insertFn) {
  return new Promise((resolve, reject) => {
    // 检查文件大小
    if (file.size > props.uploadConfig.maxImageSize) {
      ElMessage.error(`图片文件大小不能超过${props.uploadConfig.maxImageSize / 1024 / 1024}MB`)
      reject(new Error('文件大小超出限制'))
      return
    }
    
    // 检查文件类型
    if (!props.uploadConfig.allowedImageTypes.includes(file.type)) {
      ElMessage.error('不支持的图片格式')
      reject(new Error('不支持的图片格式'))
      return
    }
    
    // 使用FileAPI上传
    FileAPI.uploadFile(file).then((res) => {
      insertFn(res.url, res.name || '', res.url)
      resolve(res)
    }).catch((error) => {
      console.error('图片上传失败:', error)
      ElMessage.error('图片上传失败，请重试')
      reject(error)
    })
  })
}

// 自定义视频上传
function customVideoUpload(file, insertFn) {
  return new Promise((resolve, reject) => {
    // 检查文件大小
    if (file.size > props.uploadConfig.maxVideoSize) {
      ElMessage.error(`视频文件大小不能超过${props.uploadConfig.maxVideoSize / 1024 / 1024}MB`)
      reject(new Error('文件大小超出限制'))
      return
    }
    
    // 检查文件类型
    if (!props.uploadConfig.allowedVideoTypes.includes(file.type)) {
      ElMessage.error('不支持的视频格式')
      reject(new Error('不支持的视频格式'))
      return
    }
    
    // 使用FileAPI上传
    FileAPI.uploadFile(file).then((res) => {
      insertFn(res.url, res.name || '', res.url)
      resolve(res)
    }).catch((error) => {
      console.error('视频上传失败:', error)
      ElMessage.error('视频上传失败，请重试')
      reject(error)
    })
  })
}

// 图片上传配置
function getImageUploadConfig() {
  return {
    fieldName: 'file',
    server: props.uploadConfig.imageServer,
    maxFileSize: props.uploadConfig.maxImageSize,
    allowedFileTypes: props.uploadConfig.allowedImageTypes,
    customInsert(res, insertFn) {
      insertFn(res.url, res.name || '', res.url)
    },
    onBeforeUpload(file) {
      showUploadDialog('图片上传中...', file.name)
      return file
    },
    onProgress(progress) {
      updateUploadProgress(progress)
    },
    onSuccess(file, res) {
      hideUploadDialog()
      ElMessage.success('图片上传成功')
    },
    onFailed(file, res) {
      updateUploadStatus('exception')
      ElMessage.error(res?.message || '图片上传失败')
    },
    onError(file, err, res) {
      updateUploadStatus('exception')
      console.error('上传错误:', err)
      ElMessage.error(res?.message || '图片上传出错')
    },
    customUpload: customImageUpload
  }
}

// 视频上传配置
function getVideoUploadConfig() {
  return {
    fieldName: 'file',
    server: props.uploadConfig.videoServer,
    maxFileSize: props.uploadConfig.maxVideoSize,
    allowedFileTypes: props.uploadConfig.allowedVideoTypes,
    customInsert(res, insertFn) {
      insertFn(res.url, res.name || '', res.url)
    },
    onBeforeUpload(file) {
      showUploadDialog('视频上传中...', file.name)
      return file
    },
    onProgress(progress) {
      updateUploadProgress(progress)
    },
    onSuccess(file, res) {
      hideUploadDialog()
      ElMessage.success('视频上传成功')
    },
    onFailed(file, res) {
      updateUploadStatus('exception')
      ElMessage.error(res?.message || '视频上传失败')
    },
    onError(file, err, res) {
      updateUploadStatus('exception')
      console.error('上传错误:', err)
      ElMessage.error(res?.message || '视频上传出错')
    },
    customUpload: customVideoUpload
  }
}

// 工具栏配置
const toolbarConfig = reactive({
  excludeKeys: props.mode === 'simple' ? [
    'group-video',
    'group-more-style',
    'insertTable',
    'codeBlock',
    'divider'
  ] : []
})

// 编辑器配置
const editorConfig = reactive({
  placeholder: props.readonly ? '' : '请输入内容...',
  scroll: false,
  autoFocus: false,
  readOnly: props.readonly, // 设置只读模式
  MENU_CONF: {
    uploadImage: getImageUploadConfig(),
    uploadVideo: getVideoUploadConfig(),
    insertImage: {
      onInsertedImage(imageElem) {
        console.log('插入的图片', imageElem)
      }
    },
    insertVideo: {
      onInsertedVideo(videoElem) {
        console.log('插入的视频', videoElem)
      }
    }
  },
  EXTEND_CONF: {
    videoResize: true,
    videoStyle: {
      maxWidth: '100%',
      borderRadius: '8px',
      boxShadow: '0 2px 8px rgba(0,0,0,0.1)'
    }
  }
})

// 监听 readonly 属性变化
watch(() => props.readonly, (newVal) => {
  if (editorRef.value) {
    if (newVal) {
      editorRef.value.disable()
    } else {
      editorRef.value.enable()
    }
  }
  // 更新编辑器配置
  editorConfig.readOnly = newVal
  editorConfig.placeholder = newVal ? '' : '请输入内容...'
})

// 编辑器创建完成
function handleCreated(editor) {
  editorRef.value = editor
  // 如果只读模式，立即禁用编辑器
  if (props.readonly) {
    editor.disable()
  }
  emit('created', editor)
}

// 编辑器内容变化
function handleChange(editor) {
  // 只读模式下不触发内容变化事件
  if (props.readonly) return
  
  valueHtml.value = editor.getHtml()
  emit('update:modelValue', valueHtml.value)
  emit('change', {
    html: valueHtml.value,
    text: editor.getText()
  })
}

// 公共方法
function getEditor() {
  return editorRef.value
}

function clearContent() {
  editorRef.value?.clear()
}

function setContent(html) {
  editorRef.value?.setHtml(html)
}

function getContent() {
  if (!editorRef.value) return { html: '', text: '' }
  return {
    html: editorRef.value.getHtml(),
    text: editorRef.value.getText()
  }
}

function disable() {
  editorRef.value?.disable()
}

function enable() {
  editorRef.value?.enable()
}

// 暴露方法给父组件
defineExpose({
  getEditor,
  clearContent,
  setContent,
  getContent,
  disable,
  enable
})

// 组件销毁时清理
onBeforeUnmount(() => {
  if (editorRef.value == null) return
  editorRef.value.destroy()
})
</script>

<style scoped>
.rich-text-editor-container {
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  overflow: hidden;
}

.editor-toolbar-container {
  border-bottom: 1px solid #dcdfe6;
}

.editor-content-container {
  height: v-bind(height);
  overflow-y: auto;
}

.upload-filename {
  margin-top: 10px;
  font-size: 12px;
  color: #909399;
  text-align: center;
  word-break: break-all;
}

:deep(.w-e-text-container) {
  text-align: left !important;
  background: none !important;
  border: none !important;
  box-shadow: none !important;
}

/* 只读模式样式 */
.rich-text-editor-container.readonly {
  background-color: #f5f7fa;
  border-color: #e4e7ed;
}

.rich-text-editor-container.readonly .editor-content-container {
  background-color: #f5f7fa;
}

:deep(.w-e-text-container[data-slate-editor="true"]) {
  background: none !important;
}

/* 只读模式下的文本容器样式 */
.rich-text-editor-container.readonly :deep(.w-e-text-container) {
  background-color: #f5f7fa !important;
  cursor: default !important;
}

.rich-text-editor-container.readonly :deep(.w-e-text-container[contenteditable="true"]) {
  cursor: default !important;
  user-select: text;
  -webkit-user-select: text;
  -moz-user-select: text;
  -ms-user-select: text;
}
</style>